package com.njzxw.fs.commonutil.imp;

import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import com.njzxw.fs.commonutil.bean.FileBean;
import com.njzxw.fs.commonutil.bean.PartBean;
import com.njzxw.fs.commonutil.repository.BaseRep;
import com.njzxw.fs.commonutil.util.DateUtil;
import com.njzxw.fs.commonutil.util.FileHellp;
import com.njzxw.fs.commonutil.util.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class AliyunOssImp extends OssUtilAbs {

    @Autowired
    private BaseRep baseRep;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public boolean connect() {
        return true;
    }

    @Override
    public FileBean saveTemp(InputStream inputStream, String name, long size) {
        FileBean fileBean = exeName(name,size);
        if(fileBean == null){
            logger.warn("文件丢失");
            return null;
        }
        String filesdir = DateUtil.getToday("yyyyMMddHHmmss")+"_"+new Random().nextInt(100000);
        String dirs = common.getSystem("RESOURCE.TEMP.PATH")+"/"+ filesdir;

        String path = System.getProperty("user.dir");

        String dir = path+dirs;

        if(fileBean.getImg_host().endsWith("/")){
            fileBean.setImg_host(fileBean.getImg_host()+filesdir+"/");
        }else{
            fileBean.setImg_host(fileBean.getImg_host()+"/"+filesdir);
        }

        boolean truth = FileHellp.saveFile(inputStream,dir,fileBean.getFile_name());
        logger.debug("上传truth:"+truth);
        if(!truth){
            return null;
        }

        int exc = baseRep.insertTemp(fileBean);

        if(exc == 1){
            return fileBean;
        };

        return null;
    }

    @Override
    public boolean close() {
        return true;
    }

    @Override
    public String exeFile(String id, String path) {
        return exeFile(id,path,"1",OperType.getValue(OperType.BACKGROUND),"系统管理员");
    }

    @Override
    public String exeFile(String id, String path, String oper_id, int oper_type, String oper_name) {
        if(id.startsWith("z")){//已经在正式中存在，直接下一个

            return id.replace("z","");
        }
        FileBean fileBean = baseRep.getTempFile(id);
        logger.debug("fileBean:"+fileBean);
        if(StringUtils.isBlank(fileBean.getFile_name())){
            return "";
        }

        String fileUrlPathLocal = (fileBean.getImg_host()+fileBean.getFile_name()).replaceAll("//","/");
        //先到本地获取，如果本地能获取到不走网络配置
        logger.debug("fileUrlPathLocal:"+fileUrlPathLocal);
        String dirs = fileUrlPathLocal.substring(fileUrlPathLocal.indexOf(common.getSystem("RESOURCE.TEMP.PATH")));

        String path_ = System.getProperty("user.dir");

        String dir = path_+dirs;

        logger.debug("dir:"+dir);

        //临时下载文件
        URL url = null;
        InputStream inputStream = null;
        OSS ossClient = null;
        try {

            File file = new File(dir);

            if(file.exists()){
                inputStream = new FileInputStream(file);
            }else{
                String fileUrlPath = (fileBean.getImg_host()+fileBean.getFile_name());
                System.out.println("fileUrlPath:"+fileUrlPath);
                url = new URL(fileUrlPath);
                // 打开连接
                URLConnection con = url.openConnection();
                //设置请求超时为10s
                con.setConnectTimeout(10 * 1000);
                inputStream = con.getInputStream();
            }

            System.out.println(common.getSystem("ALIYUN.ENDPOINT")+"---"+ common.getSystem("ACCESSKEYID")+"---"+ common.getSystem("ACCESSKEYSECRET"));
            ossClient = new OSSClientBuilder().build(common.getSystem("ALIYUN.ENDPOINT"), common.getSystem("ACCESSKEYID"), common.getSystem("ACCESSKEYSECRET"));

            fileBean.setImg_host(common.getSystem("RESOURCE.IMGHOST")+path+"/");
            fileBean.setPath(path);
            fileBean.setOper_name(oper_name);

            fileBean.setOper_id(oper_id);
            fileBean.setOper_type(oper_type);
            PutObjectResult result = ossClient.putObject(common.getSystem("ALIYUN.BUCKETNAME"),fileBean.getFile_name(),inputStream);

            if(baseRep.insertFile(fileBean) != 1){
                return null;
            }
            return String.valueOf(fileBean.getId());
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        } finally {

            if(inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(ossClient != null){
                ossClient.shutdown();
            }
        }
    }

    @Override
    public List<String> exeFile(List<String> ids, String path) {

        for(int i=0;i<ids.size();i++){
            exeFile(ids.get(i),path,"1",OperType.getValue(OperType.BACKGROUND),"系统管理员");
        }

        return null;
    }

    @Override
    public List<String> exeFile(List<String> ids, String path, String oper_id, int oper_type, String oper_name) {
        for(int i=0;i<ids.size();i++){
            exeFile(ids.get(i),path,oper_id,oper_type,oper_name);
        }
        return null;
    }

    @Override
    public void createPart(PartBean partBean) throws Exception {
        super.createPart(partBean);

        //根据文件md5值进行校验是否已经
        if(StringUtils.isBlank(partBean.getEndpoint())){
            partBean.setEndpoint(common.getSystem("ALIYUN.ENDPOINT"));
        }

        if(StringUtils.isBlank(partBean.getAccessKeyId())){
            partBean.setAccessKeyId(common.getSystem("ACCESSKEYID"));
        }

        if(StringUtils.isBlank(partBean.getAccessKeySecret())){
            partBean.setAccessKeySecret(common.getSystem("ACCESSKEYSECRET"));
        }

        if(StringUtils.isBlank(partBean.getBucketName())){
            partBean.setBucketName(common.getSystem("ALIYUN.BUCKETNAME.TEMP"));
        }

        ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
        conf.setIdleConnectionTime(1000);
        OSS client = new OSSClientBuilder().build(partBean.getEndpoint(), partBean.getAccessKeyId(), partBean.getAccessKeySecret(), conf);
        partBean.setOss(client);
        partBean.setUploadId(claimUploadId(partBean));
    }

    @Override
    public void uploadPart(PartBean partBean) throws Exception {
        super.uploadPart(partBean);

        partBean.getInstream().skip(partBean.getStartPos());

        UploadPartRequest uploadPartRequest = new UploadPartRequest();
        uploadPartRequest.setBucketName(partBean.getBucketName());
        uploadPartRequest.setKey(partBean.getKey());
        uploadPartRequest.setUploadId(partBean.getUploadId());
        uploadPartRequest.setInputStream(partBean.getInstream());
        uploadPartRequest.setPartSize(partBean.getPartSize());
        uploadPartRequest.setPartNumber(partBean.getPartNumber());

        UploadPartResult uploadPartResult = partBean.getOss().uploadPart(uploadPartRequest);

        List list = redisUtil.getValueObject("upload"+partBean.getUploadId(),List.class);
        list.add(uploadPartResult.getPartETag());
        redisUtil.setKeyObject("upload"+partBean.getUploadId(),list,1L, TimeUnit.DAYS);
    }

    @Override
    public void closePart(PartBean partBean) throws Exception{
        super.closePart(partBean);

        try{
            completeMultipartUpload(partBean);
            redisUtil.deleteKey("upload"+partBean.getUploadId());
        }catch (Exception e){
            throw new Exception("关闭失败");
        }finally {
            if(partBean.getOss() != null){
                partBean.getOss().shutdown();
            }
        }

    }

    private void completeMultipartUpload(PartBean partBean) {
        List list = redisUtil.getValueObject("upload"+partBean.getUploadId(),List.class);
        // Make part numbers in ascending order
        Collections.sort(list, new Comparator<PartETag>() {

            @Override
            public int compare(PartETag p1, PartETag p2) {
                return p1.getPartNumber() - p2.getPartNumber();
            }

        });

        System.out.println("Completing to upload multiparts\n");
        CompleteMultipartUploadRequest completeMultipartUploadRequest =
                new CompleteMultipartUploadRequest(partBean.getBucketName(), partBean.getKey(), partBean.getUploadId(), list);
        partBean.getOss().completeMultipartUpload(completeMultipartUploadRequest);
    }

    private static String claimUploadId(PartBean partBean) {
        InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(partBean.getBucketName(), partBean.getKey());
        InitiateMultipartUploadResult result = partBean.getOss().initiateMultipartUpload(request);
        return result.getUploadId();
    }

}
